package com.bjpowernode.ba01;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Aspect：是aspect框架的注解.
 * 作用：表示当前类是切面类
 * 切面类：是用来给业务方法增加功能的类,在这个类有切面功能的代码
 * 位置：在类定义的上面
 */
@Aspect
public class MyAspect {
    /**
     * 定义方法,方法是实现切面功能的.
     * 方法的定义要求:
     * 1.公共方法public.
     * 2.方法没有返回值.
     * 3.方法名称自定义.
     * 4.方法可以有参数,也可以没参数(参数不是自己定义).
     *  如果有参数,参数不是自定义的,有几个参数类型可以使用.
     */

    /**
     * @Before：前置通知注解
     * 属性：value,是切入点表达式,表示切面功能的执行位置
     * 位置：在方法的定义上面
     * 特点：
     * 1.在目标方法之前先执行.
     * 2.不会改变目标方法的执行结果.
     * 3.不会影响目标方法的执行.
     */
    /**@Before(value = "execution(* *..SomeServiceImpl.do*(..))")
    public void myBefore(){
        // 就是切面要执行的功能代码
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println("前置通知切面功能:在目标方法执行前输出时间:" + format.format(new Date()));
    }*/

    /**
     * 指定通知方法中的参数:JoinPoint
     * JoinPoint(连接点):连接的是业务方法,也就是要加入切面功能的业务方法.
     * 作用是:可以在通知方法中获取方法执行的信息,例如方法名称,形参,以及方法签名等.
     * 如果你的切面功能要用到方法的信息,就需要加入JoinPoint
     * 这个JoinPoint参数的值是由框架赋予的,如果你要使用JoinPoint那么它必须在第一位
     */
    @Before(value = "execution(* *..SomeServiceImpl.do*(..))")
    public void MyBefore(JoinPoint joinPoint){
        // 获取方法的完整信息.
        System.out.println("方法的签名(定义) = " + joinPoint.getSignature());
        System.out.println("方法的名称 = " + joinPoint.getSignature().getName());
        // 获取方法的实参
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            System.out.println("参数是 = " + arg);
        }
        // 就是切面要执行的功能代码
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println("前置通知切面功能:在目标方法执行前输出时间:" + format.format(new Date()));
    }
}
